<script setup lang="ts">
import type { User } from '#/api/system/user/model';

import { ref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';
import { DictEnum } from '@vben/constants';
import { $t } from '@vben/locales';
import { getPopupContainer } from '@vben/utils';

import { useVbenForm, z } from '#/adapter/form';
import { deptTree } from '#/api/system/dept/dept';
import { getPostList } from '#/api/system/post/post';
import { getRoleList } from '#/api/system/role/role';
import { addUser, getUserOne, updateUser } from '#/api/system/user/user';
import { getDictOptions } from '#/utils/dict';

const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref<boolean>(false);
// 侧拉内置容器 Form表单的配置项
const [Form, FormApi] = useVbenForm({
  wrapperClass: 'grid-cols-2',
  commonConfig: {
    formItemClass: 'col-span-2',
    componentProps: {
      class: 'w-full',
    },
    labelWidth: 80,
  },
  // 不显示提交和重置按钮
  showDefaultActions: false,
  // 垂直布局，label和input在不同行，值为vertical
  // 水平布局，label和input在同一行
  layout: 'horizontal',
  schema: [
    {
      component: 'Input',
      fieldName: 'userId',
      dependencies: {
        show: () => false,
        triggerFields: [''],
      },
    },
    {
      component: 'Input',
      fieldName: 'userName',
      disabled: false,
      componentProps: {
        maxlength: 30,
      },
      label: '用户账号',
      rules: 'required',
    },
    {
      component: 'Input',
      fieldName: 'password',
      componentProps: {
        maxlength: 20,
        type: 'password',
      },
      label: '用户密码',
      dependencies: {
        show: (values) => {
          return values.update ? !values.update : true;
        },
        triggerFields: ['userName'],
      },
      rules: z
        .string()
        .refine((val) => val.trim() !== '', {
          message: '请输入用户密码',
        })
        .refine((val) => val.length >= 6 && val.length <= 20, {
          message: '长度需在6-20字符之间',
        }),
    },
    {
      component: 'Input',
      fieldName: 'nickName',
      componentProps: {
        maxlength: 30,
      },
      label: '用户昵称',
      rules: 'required',
    },
    {
      component: 'ApiTreeSelect',
      componentProps: {
        api: async () => {
          return await deptTree();
        },
        getPopupContainer,
        labelField: 'label',
        valueField: 'id',
        childrenField: 'children',
        checkStrictly: true,
      },
      rules: 'selectRequired',
      fieldName: 'deptId',
      label: '所属部门',
    },
    {
      component: 'Input',
      fieldName: 'phonenumber',
      componentProps: {
        maxlength: 11,
      },
      label: '手机号码',
      rules: z
        .string()
        .regex(/^1[3-9]\d{9}$/, '请输入有效的手机号')
        .refine((val) => val.length === 11, '必须是11位数字'),
    },
    {
      component: 'Input',
      fieldName: 'email',
      componentProps: {
        maxlength: 50,
      },
      label: '邮箱',
      rules: z
        .string()
        .trim()
        .refine(
          (value) =>
            // 允许空字符串或符合邮箱格式
            value === '' || z.string().email().safeParse(value).success,
          { message: '请输入有效的邮箱地址' },
        )
        .optional(),
    },
    {
      component: 'RadioGroup',
      componentProps: {
        buttonStyle: 'solid',
        isButton: true,
        options: getDictOptions(DictEnum.SYS_USER_SEX),
        optionType: 'button',
      },
      defaultValue: '0',
      fieldName: 'sex',
      formItemClass: 'col-span-2 lg:col-span-1',
      label: '性别',
    },
    {
      component: 'RadioGroup',
      componentProps: {
        buttonStyle: 'solid',
        isButton: true,
        options: getDictOptions(DictEnum.SYS_NORMAL_DISABLE),
        optionType: 'button',
      },
      fieldName: 'status',
      defaultValue: '0',
      formItemClass: 'col-span-2 lg:col-span-1',
      label: '状态',
    },
    {
      component: 'ApiSelect',
      componentProps: {
        getPopupContainer,
        api: async () => {
          const { rows } = await getPostList();
          return rows;
        },
        multiple: true,
        labelField: 'postName',
        valueField: 'postId',
      },
      fieldName: 'postIds',
      label: '岗位',
    },
    {
      component: 'ApiSelect',
      componentProps: {
        getPopupContainer,
        api: async () => {
          const { rows } = await getRoleList();
          return rows;
        },
        multiple: true,
        labelField: 'roleName',
        valueField: 'roleId',
      },
      fieldName: 'roleIds',
      label: '角色',
    },
    {
      component: 'Input',
      componentProps: {
        type: 'textarea',
        maxlength: 500,
        showWordLimit: true,
      },
      fieldName: 'remark',
      formItemClass: 'items-baseline',
      label: '备注',
    },
  ],
});

const [Drawer, DrawerApi] = useVbenDrawer({
  // 点击侧拉的确定按钮执行逻辑
  async onConfirm() {
    try {
      DrawerApi.drawerLoading(true);
      const { valid } = await FormApi.validate();
      if (!valid) {
        return;
      }
      const data = await FormApi.getValues<User>();
      await (isUpdate.value ? updateUser(data) : addUser(data));
      emit('reload');
      DrawerApi.close();
      await FormApi.resetForm();
    } catch (error) {
      console.error(error);
    } finally {
      DrawerApi.drawerLoading(false);
    }
  },
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    DrawerApi.drawerLoading(true);
    const { id, update } = DrawerApi.getData();
    isUpdate.value = update;
    /** update时 禁用用户名修改 不显示密码框 */
    FormApi.updateSchema([
      { componentProps: { disabled: isUpdate.value }, fieldName: 'userName' },
      {
        dependencies: {
          show: () => !isUpdate.value,
          triggerFields: ['userName'],
        },
        fieldName: 'password',
      },
    ]);
    if (id) {
      const result = await getUserOne(id);
      await FormApi.setValues(result.data);
      await FormApi.setFieldValue('postIds', result.postIds);
      await FormApi.setFieldValue('roleIds', result.roleIds);
    }
    DrawerApi.drawerLoading(false);
  },
});
</script>
<template>
  <Drawer
    :title="isUpdate ? $t('common.modify') : $t('common.add')"
    class="w-[600px]"
  >
    <Form />
  </Drawer>
</template>
<style scoped lang="scss">
:deep(.el-input-number) {
  width: 100%;
}

:deep(button) {
  width: 100%;
}
</style>
